<!DOCTYPE html>
<html>
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="utf-8">
  
  <title>Java并发框架AQS | gdme1320 的笔记</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="Table of Contents   Intro 用法 用法示例 ReentrantLock 中使用AQS的方法   ReentrantLock  类结构： 实现重入 公平与非公平       Intro   java.util.concurrent包中很多类都依赖于这个类所提供的队列式的同步器,比如说常用的ReentranLock,Semaphore和CountDownLatch等。">
<meta name="keywords" content="ReentrantLock">
<meta property="og:type" content="article">
<meta property="og:title" content="Java并发框架AQS">
<meta property="og:url" content="http://gdme1320.gitee.com/java/concurrent/aqs/index.html">
<meta property="og:site_name" content="gdme1320 的笔记">
<meta property="og:description" content="Table of Contents   Intro 用法 用法示例 ReentrantLock 中使用AQS的方法   ReentrantLock  类结构： 实现重入 公平与非公平       Intro   java.util.concurrent包中很多类都依赖于这个类所提供的队列式的同步器,比如说常用的ReentranLock,Semaphore和CountDownLatch等。">
<meta property="og:locale" content="default">
<meta property="og:image" content="http://gdme1320.gitee.com/java/concurrent/aqs/reentrantlock-class.png">
<meta property="og:updated_time" content="2022-03-23T09:59:41.011Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Java并发框架AQS">
<meta name="twitter:description" content="Table of Contents   Intro 用法 用法示例 ReentrantLock 中使用AQS的方法   ReentrantLock  类结构： 实现重入 公平与非公平       Intro   java.util.concurrent包中很多类都依赖于这个类所提供的队列式的同步器,比如说常用的ReentranLock,Semaphore和CountDownLatch等。">
<meta name="twitter:image" content="http://gdme1320.gitee.com/java/concurrent/aqs/reentrantlock-class.png">
  
    <link rel="alternate" href="/atom.xml" title="gdme1320 的笔记" type="application/atom+xml">
  
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" integrity="sha384-XdYbMnZ/QjLh6iI4ogqCTaIjrFk87ip+ekIjefZch0Y+PvJ8CDYtEs1ipDmPorQ+" crossorigin="anonymous">

  <link rel="stylesheet" href="/css/styles.css">
  <link rel="stylesheet" href="/css/docs.min.css">
  

</head>
</html>
<body>
  <nav class="navbar navbar-inverse">
  <div class="container">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#main-menu-navbar" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="main-menu-navbar">
      <ul class="nav navbar-nav">
        
          <li><a class href="/index.html">Home</a></li>
        
          <li><a class href="/archives/">Archives</a></li>
        
      </ul>

      <!--
      <ul class="nav navbar-nav navbar-right">
        
          <li><a href="/atom.xml" title="RSS Feed"><i class="fa fa-rss"></i></a></li>
        
      </ul>
      -->
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>

  <div class="container bs-docs-container">
  
    <div class="row">
        <div class="col-sm-8 blog-main">
          <article id="post-java/concurrent/aqs" class="article article-type-post" itemscope itemprop="blogPost">

  <header class="article-header">
    
  
    <h1 class="article-title" itemprop="name">
      Java并发框架AQS
    </h1>
  


  </header>

  <div class="article-meta">
    <div class="article-datetime">
  <a href="/java/concurrent/aqs/" class="article-date"><time datetime="2022-03-23T09:59:41.011Z" itemprop="datePublished">2022-03-23</time></a>
</div>

    
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/java/">java</a> / <a class="article-category-link" href="/categories/java/concurrent/">concurrent</a>
  </div>


  </div>
  <div class="article-inner">

    <div class="article-entry" itemprop="articleBody">
      
        
<div id="content">
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#org2dc8908">Intro</a></li>
<li><a href="#org5351169">用法</a></li>
<li><a href="#org36cb252">用法示例</a></li>
<li><a href="#orgd8cd0f8">ReentrantLock 中使用AQS的方法   <span class="tag"><span class="ReentrantLock">ReentrantLock</span></span></a>
<ul>
<li><a href="#org32c154d">类结构：</a></li>
<li><a href="#org0fbc70e">实现重入</a></li>
<li><a href="#org375c75d">公平与非公平</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="outline-2" id="outline-container-org2dc8908">
<h2 id="org2dc8908">Intro</h2>
<div class="outline-text-2" id="text-org2dc8908">
<p>
java.util.concurrent包中很多类都依赖于这个类所提供的队列式的同步器,比如说常用的ReentranLock,Semaphore和CountDownLatch等。
</p>
<p>
这个抽象类提供了一个框架，用于实现阻塞锁和其他依赖于FIFO等待队列的同步器（samephores, events等）。
</p>
<p>
这个类中有一个int变量，并提供了修改和读取该int变量的方法，例如getState(), compareAndSet，这些方法是线程安全的，提供给子类调用。
如果要实现一个同步器使用一个原子int代表状态，那么就适合使用这个类作为基类。
</p>
<p>
子类需要定义更改状态的Protected方法，还需要定义这个状态的意思。
例如实现一个简单的排他锁，就定义1为持有锁，0为空闲，然后重写下面小节中那几个方法，详细代码看下面的用法示例。
</p>
<p>
这个类中还维护了一个链表，用于提供等待队列的功能，然后这个类实现了所有链表的操作、处理链表的线程安全问题、各线程的阻塞机制。
子类不需要关心链表的细节，只需要实现下面小节中的方法。
排他模式同步器的基本形式如下
</p>
<pre class="example">
Acquire: // 加锁的流程
// tryAcquire 是子类需要实现的方法。例如一个简单的排他锁，tryAcquire方法体就是compareAndSetState(0,1)
     while (!tryAcquire(arg)) { 
        enqueue thread if it is not already queued; // 当前线程如果不在队列中就加入到队列（也就是AQS内部的链表）
        possibly block current thread; // 也许引起当前线程的阻塞
     }

Release: // 释放锁的流程
     if (tryRelease(arg)) // 只有子类实现的tryRelease返回true了，
        unblock the first queued thread; // AQS才会唤醒队列中等待的下个线程
// 难道tryRelease还能返回false吗？
// ReentrantLock，为了实现重入的功能，如果当前线程没有完全释放（当前线程加了多少次锁，就必须释放多少次），是不能唤醒下个线程的，这时就要返回false
</pre>
<p>
例如重写的tryAcquire方法如果设置状态失败了，就返回false，随后AQS交此线程加入到链表，然后当前线程阻塞，直到前面的线程释放锁。
如果又有一个线程尝试获得锁，设置state仍然是失败的，则继续被加入到等待队列中。
</p>
<p>
实现AQS的子类应当被定义为非公开的内部类。AQS本身没有继承任何同步接口。
相反，它定义了诸如 acquireInterruptibly(int) 的方法，这些方法被具体的同步器调用以实现它们的公开方法。
例如ReentrantLock中，就有两个内部类实现AQS（ReentrantLock由于支持公平和非公平两种模式，所以有两个实现类），ReentrantLock才是“具体的同步器”，
而ReentrantLock则是调用内部类的方法。
</p>
</div>
</div>
<div class="outline-2" id="outline-container-org5351169">
<h2 id="org5351169">用法</h2>
<div class="outline-text-2" id="text-org5351169">
<p>
重写下面的方法，使用 getState() , setState(int) , compareAndSet(int, int) 方法更改同步器的状态。
</p>
<ul class="org-ul">
<li>tryAcquire(int)</li>
<li>tryRelease(int)</li>
<li>tryAcquireShared(int)</li>
<li>tryReleaseShared(int)</li>
<li>isHeldExclusively()</li>
</ul>
<p>
上面的方法默认是抛出 UnsupportedOperationException 异常。这些方法的实现必须是内部线程安全的，并且是简短、不阻塞的。
重写这些方法是使用AQS的唯一方式。其他的方法都是 final 的。
</p>
<p>
AQS类中还有一些跟踪持有锁的线程的方法，我们能够使用这些方法，用于调试或监控。
</p>
</div>
</div>
<div class="outline-2" id="outline-container-org36cb252">
<h2 id="org36cb252">用法示例</h2>
<div class="outline-text-2" id="text-org36cb252">
<p>
下面是一个简单的非重入锁，使用0表示没有锁，1表示锁住状态。
</p>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold;">class</span> <span style="font-weight: bold; text-decoration: underline;">Mutex</span> <span style="font-weight: bold;">implements</span> <span style="font-weight: bold; text-decoration: underline;">Lock</span>, <span style="font-weight: bold; text-decoration: underline;">java</span>.<span style="font-weight: bold; text-decoration: underline;">io</span>.<span style="font-weight: bold; text-decoration: underline;">Serializable</span> {

    <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">继承AQS的类，被定义为内部类</span>
    <span style="font-weight: bold;">private</span> <span style="font-weight: bold;">static</span> <span style="font-weight: bold;">class</span> <span style="font-weight: bold; text-decoration: underline;">Sync</span> <span style="font-weight: bold;">extends</span> <span style="font-weight: bold; text-decoration: underline;">AbstractQueuedSynchronizer</span> {
        <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">1表示持有锁，0表示没有</span>
        <span style="font-weight: bold;">protected</span> <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold;">isHeldExclusively</span>() {
            <span style="font-weight: bold;">return</span> getState() == 1;
        }

        <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">Override acquire</span>
        <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold;">tryAcquire</span>(<span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">acquires</span>) {
            <span style="font-weight: bold; text-decoration: underline;">assert</span> <span style="font-weight: bold; font-style: italic;">acquires</span> == 1; <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">加锁，应当将状态设置为1</span>
            <span style="font-weight: bold;">if</span> (compareAndSetState(0, 1)) { <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">CAS方法，线程安全地设置状态</span>
                setExclusiveOwnerThread(Thread.currentThread());
                <span style="font-weight: bold;">return</span> <span style="font-weight: bold; text-decoration: underline;">true</span>;
            }
            <span style="font-weight: bold;">return</span> <span style="font-weight: bold; text-decoration: underline;">false</span>; <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">设置状态失败，加锁失败</span>
        }

        <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">Override release</span>
        <span style="font-weight: bold;">protected</span> <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold;">tryRelease</span>(<span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">releases</span>) {
            <span style="font-weight: bold; text-decoration: underline;">assert</span> <span style="font-weight: bold; font-style: italic;">releases</span> == 1; <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">Otherwise unused</span>
            <span style="font-weight: bold;">if</span> (getState() == 0) <span style="font-weight: bold;">throw</span> <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">IllegalMonitorStateException</span>();
            setExclusiveOwnerThread(<span style="font-weight: bold; text-decoration: underline;">null</span>);
            setState(0);
            <span style="font-weight: bold;">return</span> <span style="font-weight: bold; text-decoration: underline;">true</span>;
        }

        <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">Provides a Condition</span>
        <span style="font-weight: bold; text-decoration: underline;">Condition</span> <span style="font-weight: bold;">newCondition</span>() { <span style="font-weight: bold;">return</span> <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">ConditionObject</span>(); }

        <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">Deserializes properly</span>
        <span style="font-weight: bold;">private</span> <span style="font-weight: bold; text-decoration: underline;">void</span> <span style="font-weight: bold;">readObject</span>(<span style="font-weight: bold; text-decoration: underline;">ObjectInputStream</span> <span style="font-weight: bold; font-style: italic;">s</span>)
            <span style="font-weight: bold;">throws</span> <span style="font-weight: bold; text-decoration: underline;">IOException</span>, <span style="font-weight: bold; text-decoration: underline;">ClassNotFoundException</span> {
            s.defaultReadObject();
            setState(0); <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">reset to unlocked state</span>
        }
    }

    <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">内部类Sync，执行所有的锁操作，外部类的锁方法都通过这个内部类实现</span>
    <span style="font-weight: bold;">private</span> <span style="font-weight: bold;">final</span> <span style="font-weight: bold; text-decoration: underline;">Sync</span> <span style="font-weight: bold; font-style: italic;">sync</span> = <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">Sync</span>();

    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">void</span> <span style="font-weight: bold;">lock</span>()                { sync.acquire(1); }
    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold;">tryLock</span>()          { <span style="font-weight: bold;">return</span> sync.tryAcquire(1); }
    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">void</span> <span style="font-weight: bold;">unlock</span>()              { sync.release(1); }
    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">Condition</span> <span style="font-weight: bold;">newCondition</span>()   { <span style="font-weight: bold;">return</span> sync.newCondition(); }
    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold;">isLocked</span>()         { <span style="font-weight: bold;">return</span> sync.isHeldExclusively(); }
    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold;">hasQueuedThreads</span>() { <span style="font-weight: bold;">return</span> sync.hasQueuedThreads(); }
    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">void</span> <span style="font-weight: bold;">lockInterruptibly</span>() <span style="font-weight: bold;">throws</span> <span style="font-weight: bold; text-decoration: underline;">InterruptedException</span> {
        sync.acquireInterruptibly(1);
    }
    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold;">tryLock</span>(<span style="font-weight: bold; text-decoration: underline;">long</span> <span style="font-weight: bold; font-style: italic;">timeout</span>, <span style="font-weight: bold; text-decoration: underline;">TimeUnit</span> <span style="font-weight: bold; font-style: italic;">unit</span>)
        <span style="font-weight: bold;">throws</span> <span style="font-weight: bold; text-decoration: underline;">InterruptedException</span> {
        <span style="font-weight: bold;">return</span> sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }
}
</pre>
</div>
</div>
</div>
<div class="outline-2" id="outline-container-orgd8cd0f8">
<h2 id="orgd8cd0f8">ReentrantLock 中使用AQS的方法   <span class="tag"><span class="ReentrantLock">ReentrantLock</span></span></h2>
<div class="outline-text-2" id="text-orgd8cd0f8">
<p>
ReentrantLock与前面那个简单的排他锁相比，多了两个特征：重入，公平/非公平。
</p>
</div>
<div class="outline-3" id="outline-container-org32c154d">
<h3 id="org32c154d">类结构：</h3>
<div class="outline-text-3" id="text-org32c154d">
<div class="figure">
<p><img alt="reentrantlock-class.png" src="reentrantlock-class.png">
</p>
</div>
<p>
ReentrantLock中一个Sync引用，然后调用Sync中的方法。ReentrantLock的构造方法，如果没有指定fair，则默认创建NonfairSync子类。
</p>
</div>
</div>
<div class="outline-3" id="outline-container-org0fbc70e">
<h3 id="org0fbc70e">实现重入</h3>
<div class="outline-text-3" id="text-org0fbc70e">
<p>
ReentrantLock使用0表示没有锁。面每次线程请求锁的时候，会判断当前线程是否已经获得了锁，如果是就将状态加一。
释放锁的时候，每次调用都将状态减一。
同一个线程调用了acquire多少次，就必须release多少次，到最后，状态为0了，这个线程就释放了锁。
</p>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold;">protected</span> <span style="font-weight: bold;">final</span> <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold;">tryRelease</span>(<span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">releases</span>) {
    <span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">c</span> = getState() - releases;
    <span style="font-weight: bold;">if</span> (Thread.currentThread() != getExclusiveOwnerThread())
        <span style="font-weight: bold;">throw</span> <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">IllegalMonitorStateException</span>();
    <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold; font-style: italic;">free</span> = <span style="font-weight: bold; text-decoration: underline;">false</span>;
    <span style="font-weight: bold;">if</span> (c == 0) { <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">只有 状态为0的时候，才返回true，这样，AQS中的release才能移除此结点。</span>
        free = <span style="font-weight: bold; text-decoration: underline;">true</span>;
        setExclusiveOwnerThread(<span style="font-weight: bold; text-decoration: underline;">null</span>);
    }
    setState(c); <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">如果 state = 0 了，非公平锁的模式下，ASQ还没来得及通知队列中的后继结点，其他线程立即就能插队了，下面的小节↓↓</span>
    <span style="font-weight: bold;">return</span> free;
}
</pre>
</div>
</div>
</div>
<div class="outline-3" id="outline-container-org375c75d">
<h3 id="org375c75d">公平与非公平</h3>
<div class="outline-text-3" id="text-org375c75d">
<p>
实现非公平锁：ReentrantLock每次acquire的时候，立即尝试加锁，而不是进入队列中等待。如果加锁失败，还是进入队列中等待。
在setState(0)到AQS通知队列中下个结点的时间内，其他线程就能趁虚而入，而不是排队。
</p>
<p>
非公平模式比公平模式并发高点。
</p>
<p>
非公平模式的acquire方法：
</p>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold;">final</span> <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold;">nonfairTryAcquire</span>(<span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">acquires</span>) {
    <span style="font-weight: bold;">final</span> <span style="font-weight: bold; text-decoration: underline;">Thread</span> <span style="font-weight: bold; font-style: italic;">current</span> = Thread.currentThread();
    <span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">c</span> = getState();
    <span style="font-weight: bold;">if</span> (c == 0) {
        <span style="font-weight: bold;">if</span> (compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            <span style="font-weight: bold;">return</span> <span style="font-weight: bold; text-decoration: underline;">true</span>;
        }
    }
    <span style="font-weight: bold;">else</span> <span style="font-weight: bold;">if</span> (current == getExclusiveOwnerThread()) {
        <span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">nextc</span> = c + acquires;
        <span style="font-weight: bold;">if</span> (nextc &lt; 0) <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">overflow</span>
            <span style="font-weight: bold;">throw</span> <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">Error</span>(<span style="font-style: italic;">"Maximum lock count exceeded"</span>);
        setState(nextc);
        <span style="font-weight: bold;">return</span> <span style="font-weight: bold; text-decoration: underline;">true</span>;
    }
    <span style="font-weight: bold;">return</span> <span style="font-weight: bold; text-decoration: underline;">false</span>;
}
</pre>
</div>
<p>
比较一下公平锁acquire方法：公平锁，在acquire的时候，会判断前面有没有等待的线程，如果有则排队。
</p>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold;">protected</span> <span style="font-weight: bold;">final</span> <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold;">tryAcquire</span>(<span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">acquires</span>) {
    <span style="font-weight: bold;">final</span> <span style="font-weight: bold; text-decoration: underline;">Thread</span> <span style="font-weight: bold; font-style: italic;">current</span> = Thread.currentThread();
    <span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">c</span> = getState();
    <span style="font-weight: bold;">if</span> (c == 0) { <span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">即使 state为0，还要判断它前面有没有排队的。否则返回false，由AQS将当前线程加入到排队中。</span>
        <span style="font-weight: bold;">if</span> (!hasQueuedPredecessors() &amp;&amp;
            compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            <span style="font-weight: bold;">return</span> <span style="font-weight: bold; text-decoration: underline;">true</span>;
        }
    }
    <span style="font-weight: bold;">else</span> <span style="font-weight: bold;">if</span> (current == getExclusiveOwnerThread()) {
        <span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">nextc</span> = c + acquires;
        <span style="font-weight: bold;">if</span> (nextc &lt; 0)
            <span style="font-weight: bold;">throw</span> <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">Error</span>(<span style="font-style: italic;">"Maximum lock count exceeded"</span>);
        setState(nextc);
        <span style="font-weight: bold;">return</span> <span style="font-weight: bold; text-decoration: underline;">true</span>;
    }
    <span style="font-weight: bold;">return</span> <span style="font-weight: bold; text-decoration: underline;">false</span>;
}
</pre>
</div>
</div>
</div>
</div>
</div>
<div class="status" id="postamble">
<p class="author">Author: gdme1320</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer" target="_blank" rel="noopener">Validate</a></p>
</div>

      
    </div>

    
      

    

    <footer class="article-footer">
      <a data-url="http://gdme1320.gitee.com/java/concurrent/aqs/" data-id="cl13eo7mr00ephjv432dso62h" class="article-share-link">
        <i class="fa fa-share"></i> Share
      </a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/ReentrantLock/">ReentrantLock</a></li></ul>


    </footer>
  </div>
  
    
<ul id="article-nav" class="nav nav-pills nav-justified">
  
  <li role="presentation">
    <a href="/java/spring-amqp/receive-message/" id="article-nav-older" class="article-nav-link-wrap">
      <i class="fa fa-chevron-left pull-left"></i>
      <span class="article-nav-link-title">Receiving Message</span>
    </a>
  </li>
  
  
  <li role="presentation">
    <a href="/java/concurrent/ReentrantLock/" id="article-nav-newer" class="article-nav-link-wrap">
      <span class="article-nav-link-title">Java ReentrantLock 重入锁</span>
      <i class="fa fa-chevron-right pull-right"></i>
    </a>
  </li>
  
</ul>


  
</article>




        </div>
        <div class="col-sm-3 col-sm-offset-1 blog-sidebar">
          
  
  <div class="sidebar-module">
    <h4>Categories</h4>
    <ul class="sidebar-module-list"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/apps/">apps</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/architecture/">architecture</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/devops/">devops</a><span class="sidebar-module-list-count">10</span><ul class="sidebar-module-list-child"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/devops/kubectl/">kubectl</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/devops/kubernetes/">kubernetes</a><span class="sidebar-module-list-count">3</span></li></ul></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/dotnet/">dotnet</a><span class="sidebar-module-list-count">3</span><ul class="sidebar-module-list-child"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/dotnet/entityframework/">entityframework</a><span class="sidebar-module-list-count">1</span></li></ul></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/elasticsearch/">elasticsearch</a><span class="sidebar-module-list-count">4</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/emacs/">emacs</a><span class="sidebar-module-list-count">4</span><ul class="sidebar-module-list-child"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/emacs/org-mode/">org-mode</a><span class="sidebar-module-list-count">3</span></li></ul></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/git/">git</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/graphql/">graphql</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/groovy/">groovy</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/java/">java</a><span class="sidebar-module-list-count">52</span><ul class="sidebar-module-list-child"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/java/concurrent/">concurrent</a><span class="sidebar-module-list-count">4</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/java/jackson/">jackson</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/java/shiro/">shiro</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/java/spring/">spring</a><span class="sidebar-module-list-count">11</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/java/spring-amqp/">spring-amqp</a><span class="sidebar-module-list-count">5</span><ul class="sidebar-module-list-child"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/java/spring-amqp/spring-jpa/">spring-jpa</a><span class="sidebar-module-list-count">1</span></li></ul></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/java/spring-jpa/">spring-jpa</a><span class="sidebar-module-list-count">10</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/java/spring-security/">spring-security</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/java/thymeleaf/">thymeleaf</a><span class="sidebar-module-list-count">2</span><ul class="sidebar-module-list-child"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/java/thymeleaf/maven/">maven</a><span class="sidebar-module-list-count">1</span></li></ul></li></ul></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/jenkins/">jenkins</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/journal/">journal</a><span class="sidebar-module-list-count">7</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/js/">js</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/linux/">linux</a><span class="sidebar-module-list-count">35</span><ul class="sidebar-module-list-child"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/linux/kde/">kde</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/linux/kross/">kross</a><span class="sidebar-module-list-count">3</span><ul class="sidebar-module-list-child"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/linux/kross/ktorrent-scripts/">ktorrent-scripts</a><span class="sidebar-module-list-count">1</span></li></ul></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/linux/shell/">shell</a><span class="sidebar-module-list-count">6</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/linux/tcp/">tcp</a><span class="sidebar-module-list-count">1</span></li></ul></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/lisp/">lisp</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/mongodb/">mongodb</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/mssql/">mssql</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/mysql/">mysql</a><span class="sidebar-module-list-count">12</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/nginx/">nginx</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/node/">node</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/postgresql/">postgresql</a><span class="sidebar-module-list-count">2</span><ul class="sidebar-module-list-child"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/postgresql/client/">client</a><span class="sidebar-module-list-count">1</span></li></ul></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/python/">python</a><span class="sidebar-module-list-count">19</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/regex/">regex</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/rfc/">rfc</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/vim/">vim</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/windows/">windows</a><span class="sidebar-module-list-count">7</span></li></ul>
  </div>



  
  <div class="sidebar-module">
    <h4>Tags</h4>
    <ul class="sidebar-module-list"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/ReentrantLock/">ReentrantLock</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/nohup/">nohup</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/pandoc/">pandoc</a><span class="sidebar-module-list-count">1</span></li></ul>
  </div>



  
  <div class="sidebar-module">
    <h4>Tag Cloud</h4>
    <p class="tagcloud">
      <a href="/tags/ReentrantLock/" style="font-size: 10px;">ReentrantLock</a> <a href="/tags/nohup/" style="font-size: 10px;">nohup</a> <a href="/tags/pandoc/" style="font-size: 10px;">pandoc</a>
    </p>
  </div>


  
  <div class="sidebar-module">
    <h4>Archives</h4>
    <ul class="sidebar-module-list"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2919/06/">June 2919</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2022/03/">March 2022</a><span class="sidebar-module-list-count">58</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2022/01/">January 2022</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2021/11/">November 2021</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2021/10/">October 2021</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2021/04/">April 2021</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2021/03/">March 2021</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2021/02/">February 2021</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2021/01/">January 2021</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2020/12/">December 2020</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2020/11/">November 2020</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2020/10/">October 2020</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2020/09/">September 2020</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2020/07/">July 2020</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2020/06/">June 2020</a><span class="sidebar-module-list-count">10</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2020/04/">April 2020</a><span class="sidebar-module-list-count">4</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2020/03/">March 2020</a><span class="sidebar-module-list-count">8</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2020/02/">February 2020</a><span class="sidebar-module-list-count">4</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2020/01/">January 2020</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/12/">December 2019</a><span class="sidebar-module-list-count">7</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/11/">November 2019</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/10/">October 2019</a><span class="sidebar-module-list-count">11</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/09/">September 2019</a><span class="sidebar-module-list-count">6</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/08/">August 2019</a><span class="sidebar-module-list-count">4</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/07/">July 2019</a><span class="sidebar-module-list-count">10</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/06/">June 2019</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/05/">May 2019</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/04/">April 2019</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/03/">March 2019</a><span class="sidebar-module-list-count">8</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/02/">February 2019</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2019/01/">January 2019</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2018/11/">November 2018</a><span class="sidebar-module-list-count">4</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2018/10/">October 2018</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2018/08/">August 2018</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2018/07/">July 2018</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2018/06/">June 2018</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2018/03/">March 2018</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2017/07/">July 2017</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2017/06/">June 2017</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2017/04/">April 2017</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2015/05/">May 2015</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/1970/01/">January 1970</a><span class="sidebar-module-list-count">9</span></li></ul>
  </div>



  
  <div class="sidebar-module">
    <h4>Recents</h4>
    <ul class="sidebar-module-list">
      
        <li>
          <a href="/java/acessing-generic-types-at-runtime/">获取泛型类型</a>
        </li>
      
        <li>
          <a href="/linux/shell/bash_cgi/">Script for Shell Parsing Parameters</a>
        </li>
      
        <li>
          <a href="/linux/shell/shell-script/">Shell Script Getting Start</a>
        </li>
      
        <li>
          <a href="/linux/tcp/network-tcp-performance-turning-with-sysctl/">【翻译】Sysctl调节Linux网络性能</a>
        </li>
      
        <li>
          <a href="/java/concurrent/aqs-src/">AQS源码笔记</a>
        </li>
      
    </ul>
  </div>



        </div>
    </div>
  </div>
  <footer class="blog-footer">
  <div class="container">
    <div id="footer-info" class="inner">
      &copy; 2022 gdme1320<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

  

<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script> -->

<script src="/js/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>



<script src="/js/script.js"></script>

</body>
</html>
